home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / text / edit / tecoc-146.lha / baksrc.c < prev    next >
C/C++ Source or Header  |  1991-07-05  |  10KB  |  368 lines

  1. /*****************************************************************************
  2.  
  3.     BakSrc()
  4.  
  5.     This recursive function does a backward search in the edit buffer,
  6. looking for a string which will match the first match construct in the search
  7. buffer.  Basically,  it is the high-speed part of the search algorithm: it
  8. scans the edit buffer looking for the first character in the search string.
  9.     On entry, SStPtr points to the first match construct in the search
  10. buffer.  On exit,  SStPtr points to the last character of the first match
  11. construct in the search buffer.
  12.     SBfPtr points to the character following the last character in
  13. the search string.  This function does not modify SBfPtr.
  14.     On entry,  EBPtr1 points to the place in the edit buffer where
  15. the search starts.  On exit,  if the search was successful,  EBPtr1 will
  16. point to the found character.  If the search was unsuccessful,  EBPtr1 will
  17. be less than EndSAr.
  18.     On entry,  EBPtr2 is undefined.  On exit,  if the search was
  19. successful,  EBPtr2 points to the last character of the found string.  If
  20. the search was unsuccessful,  EBPtr2 is undefined.
  21.     EndSAr points to the end of the search area (where the search ends).
  22. Note that for backwards searches,  EndSAr is less than EBPtr1.  This function
  23. does not modify EndSAr.
  24.  
  25.     Match constructs are:
  26.  
  27.     ^X        match any character
  28.     ^S        match a separator character (not letter or digit)
  29.     ^N        match anything but following match construct
  30.     ^EA        match any alphabetic
  31.     ^EB        match a separator character (not letter or digit)
  32.     ^EC        match symbol constituent
  33.     ^ED        match any digit
  34.     ^EGq        match any character in q-register q
  35.     ^EL        match any line terminator (LF, VT, FF)
  36.     ^EM        match non-null string of following match construct
  37.     ^ER        match any alphanumeric
  38.     ^ES        match non-null string of spaces and/or tabs
  39.     ^EV        match lowercase alphabetic
  40.     ^EW        match uppercase alphabetic
  41.     ^EX        match any character
  42.     ^E<nnn>        match character with ASCII code nnn (octal)
  43.     ^E[x1,x2,...xn]    match any of the match constructs x1, x2, etc.
  44.     else        match the character itself
  45.  
  46. *****************************************************************************/
  47.  
  48. #include "zport.h"        /* define portability identifiers */
  49. #include "tecoc.h"        /* define general identifiers */
  50. #include "defext.h"        /* define external global variables */
  51. #include "dchars.h"        /* define identifiers for characters */
  52. #include "chmacs.h"        /* define character processing macros */
  53. #include "deferr.h"        /* define identifiers for error messages */
  54.  
  55. DEFAULT BakSrc()        /* forward search for 1st search char */
  56. {
  57.     unsigned char Charac;    /* holds a character */
  58.     charptr    LstBeg;        /* beginning of ^E[x1,x2,...] list */
  59.     char    OtCase;        /* "other" case character */
  60.     charptr    QRPtr;        /* pointer into q-register text */
  61.     BOOLEAN    SamChr;        /* same character indicator */
  62.     charptr    SavEP2;        /* temporary holder of EBPtr2 */
  63.     charptr    SavSSP;        /* temporary holder of SStPtr */
  64.     DEFAULT    Status;        /* FindQR() status for ^EGq */
  65.     charptr    TCBfPt;        /* temporary holder of CBfPtr */
  66.     charptr    TCStEn;        /* temporary holder of CStEnd */
  67.     LONG    TmpLng;        /* holds octal number for ^E<nnn> */
  68.  
  69. #if DEBUGGING
  70.     static char *DbgFNm = "BakSrc";
  71.     sprintf(DbgSBf,"*SStPtr = '%c', *EBPtr1 = '%c'", *SStPtr, *EBPtr1);
  72.     DbgFEn(3,DbgFNm,DbgSBf);
  73. #endif
  74.  
  75.     switch (*SStPtr) {
  76.     case CTRL_X:    /* ^X match any char */
  77.             break;
  78.  
  79.     case CTRL_S:    /* ^S match separator char */
  80.         for (; EBPtr1 >= EndSAr; --EBPtr1) {
  81.             if (!Is_Alnum(*EBPtr1)) {
  82.             break;
  83.         }
  84.         }
  85.         break;
  86.  
  87.     case CTRL_N:    /* ^Nx match any BUT next match construct */
  88.         if (++SStPtr == SBfPtr) {
  89.             ErrMsg(ERR_ISS);        /* illegal search string */
  90.         DBGFEX(3,DbgFNm,"FAILURE, no ^N arg");
  91.         return FAILURE;
  92.         }
  93.         SavSSP = SStPtr;
  94.         for (;EBPtr1>=EndSAr;--EBPtr1) {
  95.             EBPtr2 = EBPtr1;
  96.         SStPtr = SavSSP;
  97.         if (CMatch(&SamChr) == FAILURE) {
  98.             DBGFEX(3,DbgFNm,"FAILURE, CMatch failed");
  99.             return FAILURE;
  100.         }
  101.         if (!SamChr) {
  102.             break;
  103.         }
  104.         }
  105.         break;
  106.  
  107.     case CTRL_E:    /* ^E match construct */
  108.         if (++SStPtr == SBfPtr) {
  109.             ErrMsg(ERR_ICE);    /* ICE = illegal ^E */
  110.         DBGFEX(3,DbgFNm,"FAILURE, no ^E arg");
  111.         return FAILURE;
  112.         }
  113.         switch (To_Upper(*SStPtr)) {
  114.             case 'A':    /* ^EA match any alphabetic */
  115.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  116.                 if (Is_Alpha(*EBPtr1)) {
  117.                 break;
  118.             }
  119.             }
  120.             break;
  121.  
  122.         case 'B':    /* ^EB match any separator (==^S) */
  123.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  124.                 if (!Is_Alnum(*EBPtr1)) {
  125.                 break;
  126.             }
  127.             }
  128.             break;
  129.  
  130.         case 'C':    /* ^EC match symbol constitient */
  131.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  132.                 if (Is_SyCon(*EBPtr1)) {
  133.                 break;
  134.             }
  135.             }
  136.             break;
  137.  
  138.         case 'D':    /* ^ED match any digit */
  139.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  140.                 if (Is_Digit(*EBPtr1)) {
  141.                 break;
  142.             }
  143.             }
  144.             break;
  145.  
  146.         case 'G':    /* ^EGq match any char in Q-reg q */
  147.             if (++SStPtr == SBfPtr) {
  148.                 ErrMsg(ERR_ICE);
  149.             DBGFEX(3,DbgFNm,"FAILURE, no ^EG arg");
  150.             return FAILURE;
  151.             }
  152.             TCBfPt = CBfPtr;    /* save CBfPtr */
  153.             TCStEn = CStEnd;    /* save CStEnd */
  154.             CBfPtr = SStPtr;
  155.             CStEnd = SBfPtr;
  156.             Status = FindQR();
  157.             SStPtr = CBfPtr;
  158.             SBfPtr = CStEnd;
  159.             CBfPtr = TCBfPt;    /* restore CBfPtr */
  160.             CStEnd = TCStEn;    /* restore CStEnd */
  161.             if (Status == FAILURE) {
  162.                 DBGFEX(3,DbgFNm,"FAILURE, ^EG FindQR failed");
  163.                 return FAILURE;
  164.             }    
  165.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  166.                 QRPtr = QR->Start;
  167.             while (QRPtr < QR->End_P1) {
  168.                 if (*QRPtr++ == *EBPtr1) {
  169.                     goto kludge;
  170.                 }
  171.             }
  172.             }
  173. kludge:            break;
  174.  
  175.         case 'L':    /* ^EL match line terminator */
  176.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  177.                 if (IsEOL(*EBPtr1)) {
  178.                 break;
  179.             }
  180.             }
  181.             break;
  182.  
  183.         case 'M':    /* ^EM match multiple next constructs */
  184.             if (++SStPtr == SBfPtr) {
  185.                 ErrMsg(ERR_ICE);
  186.             DBGFEX(3,DbgFNm,"FAILURE, no ^EM arg");
  187.             return FAILURE;
  188.             }
  189.             SavSSP = SStPtr;
  190.             if (BakSrc() == FAILURE) {
  191.                 DBGFEX(3,DbgFNm,"FAILURE");
  192.             return FAILURE;
  193.             }
  194.             if (EBPtr1 < EndSAr) {    /* if not found */
  195.                 break;
  196.             }
  197.             SavEP2 = EBPtr2;
  198.             while (EBPtr1 > EndSAr) {
  199.                 EBPtr1--;
  200.             EBPtr2 = EBPtr1;
  201.             SStPtr = SavSSP;
  202.             if (CMatch(&SamChr) == FAILURE) {
  203.                 DBGFEX(3,DbgFNm,"FAILURE");
  204.                 return FAILURE;
  205.             }
  206.             if (!SamChr) {
  207.                 EBPtr1++;
  208.                 EBPtr2 = SavEP2;
  209.                 break;
  210.             }
  211.             }
  212.             DBGFEX(3,DbgFNm,"SUCCESS");
  213.             return SUCCESS;
  214.  
  215.         case 'R':    /* ^ER match any alphanumeric */
  216.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  217.                 if (Is_Alnum(*EBPtr1)) {
  218.                 break;
  219.             }
  220.             }
  221.             break;
  222.  
  223.         case 'S':    /* ^ES match any spaces/tabs */
  224.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  225.                 if ((*EBPtr1 == SPACE) || (*EBPtr1 == TABCHR)) {
  226.                 EBPtr2 = EBPtr1;
  227.                 while (EBPtr1 > EndSAr) {
  228.                     EBPtr1--;
  229.                 if ((*EBPtr1 != SPACE) &&
  230.                     (*EBPtr1 != TABCHR)) {
  231.                     EBPtr1++;
  232.                     break;
  233.                 }
  234.                 }
  235.                 DBGFEX(3,DbgFNm,"SUCCESS");
  236.                 return SUCCESS;
  237.             }
  238.             }
  239.             break;
  240.  
  241.         case 'V':    /* ^EV match any lowercase char */
  242.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  243.                 if (Is_Lower(*EBPtr1)) {
  244.                 break;
  245.             }
  246.             }
  247.             break;
  248.  
  249.         case 'W':    /* ^EW match any uppercase character */
  250.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  251.                 if (Is_Upper(*EBPtr1)) {
  252.                     break;
  253.             }
  254.             }
  255.             break;
  256.  
  257.         case 'X':    /* ^EX match any char (==^X) */
  258.             break;
  259.  
  260.         case '<':    /* ^E<n> match char w/ASCII octal code n */
  261.             if (++SStPtr == SBfPtr) {
  262.                 ErrMsg(ERR_ICE);
  263.             DBGFEX(3,DbgFNm,"FAILURE, no ^E<> arg");
  264.             return FAILURE;
  265.             }
  266.             TmpLng = 0;
  267.             while (Is_Digit(*SStPtr)) {
  268.                 TmpLng = (TmpLng * 8) + (*SStPtr - '0');
  269.             if (TmpLng > 127) {
  270.                 ErrMsg(ERR_ICE);
  271.                 DBGFEX(3,DbgFNm,"FAILURE");
  272.                 return FAILURE;
  273.             }
  274.             if (++SStPtr == SBfPtr) {
  275.                 ErrMsg(ERR_ICE);
  276.                 DBGFEX(3,DbgFNm,"FAILURE");
  277.                 return FAILURE;
  278.             }
  279.             }
  280.             if (*SStPtr != '>') {
  281.                 ErrMsg(ERR_ICE);
  282.             DBGFEX(3,DbgFNm,"FAILURE");
  283.             return FAILURE;
  284.             }
  285.             Charac = (unsigned char)TmpLng;
  286.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  287.                 if (*EBPtr1 == Charac) {
  288.                 break;
  289.             }
  290.             }
  291.             break;
  292.  
  293.         case '[':    /* ^E[x1,x2,...] match any one of x1,x2,... */
  294.             if (++SStPtr == SBfPtr) {
  295.                 ErrMsg(ERR_ICE);
  296.             DBGFEX(3,DbgFNm,"FAILURE, no ^E[] arg");
  297.             return FAILURE;
  298.             }
  299.             LstBeg = SStPtr;
  300.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  301.             while (*SStPtr != ']') {
  302.                     if (*SStPtr == ',') {
  303.                     if (++SStPtr == SBfPtr) {
  304.                         ErrMsg(ERR_ICE);
  305.                     DBGFEX(3,DbgFNm,"FAILURE");
  306.                     return FAILURE;
  307.                 }
  308.                 } else {
  309.                     EBPtr2 = EBPtr1;
  310.                 if (CMatch(&SamChr) == FAILURE) {
  311.                         DBGFEX(3,DbgFNm,"FAILURE");
  312.                     return FAILURE;
  313.                 }
  314.                 if (SamChr) {
  315.                         while (*SStPtr != ']') {
  316.                         if (++SStPtr == SBfPtr) {
  317.                             ErrMsg(ERR_ICE);
  318.                         DBGFEX(3,DbgFNm,"FAILURE");
  319.                         return FAILURE;
  320.                     }
  321.                     }
  322.                     EBPtr2 = EBPtr1;
  323.                     DBGFEX(3,DbgFNm,"SUCCESS");
  324.                     return SUCCESS;
  325.                 }
  326.                 if (++SStPtr == SBfPtr) {
  327.                         ErrMsg(ERR_ICE);
  328.                     DBGFEX(3,DbgFNm,"FAILURE");
  329.                     return FAILURE;
  330.                 }
  331.                 }
  332.             }
  333.             SStPtr = LstBeg;
  334.             }
  335.             break;
  336.  
  337.         default:
  338.             ErrMsg(ERR_ICE);
  339.             DBGFEX(3,DbgFNm,"FAILURE, bad ^E arg");
  340.             return FAILURE;
  341.         } /* end of ^E switch */
  342.         break;
  343.  
  344.     default:    /* edit buffer char must match search string char */
  345.         if (SMFlag) {            /* if case dependence */
  346.             for (; EBPtr1 >= EndSAr; --EBPtr1) {
  347.             if (*EBPtr1 == *SStPtr) {
  348.                 break;
  349.             }
  350.         }
  351.         } else {            /* else case independence */
  352.             OtCase = Is_Upper(*SStPtr)
  353.                      ? To_Lower(*SStPtr)
  354.                  : To_Upper(*SStPtr);
  355.         for (; EBPtr1 >= EndSAr; --EBPtr1) {
  356.             if ((*EBPtr1 == *SStPtr) || (*EBPtr1 == OtCase)) {
  357.                 break;
  358.             }
  359.         }
  360.         }
  361.     } /* end of switch */
  362.  
  363.  
  364.     EBPtr2 = EBPtr1;
  365.     DBGFEX(3,DbgFNm,"SUCCESS");
  366.     return SUCCESS;
  367. }
  368.